package com.wd.live.ui.activity

import android.os.Bundle
import android.util.Log
import android.view.SurfaceView
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView.Adapter
import com.google.gson.Gson
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.wd.live.BaseActivity
import com.wd.live.BaseConstant
import com.wd.live.databinding.ActivityOpenLiveBinding
import com.wd.live.databinding.ItemLiveMessageZoneBinding
import com.wd.live.tool.BindingViewHolder
import com.wd.live.tool.LocalData
import com.wd.live.tool.getUserId
import com.wd.live.tool.longToast
import com.wd.live.tool.newBindingViewHolder
import com.wd.live.tool.socket.WebSocketUtils
import com.wd.live.tool.viewBinding
import com.wd.live.viewmodel.OpenLiveViewModel
import io.agora.rtc2.ChannelMediaOptions
import io.agora.rtc2.Constants
import io.agora.rtc2.IRtcEngineEventHandler
import io.agora.rtc2.RtcEngine
import io.agora.rtc2.RtcEngineConfig
import io.agora.rtc2.video.VideoCanvas
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File


class OpenLiveActivity : BaseActivity() {
    private lateinit var mAdapter: MyAdapter
    private var liveId: Int = 0
    private val bind: ActivityOpenLiveBinding by viewBinding()
    private val viewModel: OpenLiveViewModel by viewModels()
    private var mRtcEngine: RtcEngine? = null
    private var liveCoverImage: MultipartBody.Part? = null

    // 填写项目的 App ID，可在声网控制台中生成。
    private val appId = BaseConstant.OPEN_LIVE_ID;


    // 填写声网控制台中生成的临时 Token。
    private val mRtcEventHandler: IRtcEngineEventHandler = object : IRtcEngineEventHandler() {
        override fun onError(err: Int) {
            super.onError(err)

        }

        // 监听频道内的远端主播，获取主播的 uid 信息。
        override fun onUserJoined(uid: Int, elapsed: Int) {
            runOnUiThread { // 从 onUserJoined 回调获取 uid 后，调用 setupRemoteVideo，设置远端视频视图。
                setupRemoteVideo(uid)
            }
        }

        /**
         * 当我们加入频道成功，此方法会被回调
         */
        override fun onJoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) {
            /**
             * 通知服务器推流成功
             */
            viewModel.startPushStream(liveId)
            super.onJoinChannelSuccess(channel, uid, elapsed)
        }

    }

    /**
     * 1、权限，开启这个页面，或者点击开播的时候申请
     * 2、申请开播。调用申请开播接口（服务端），我们自己的userId,告诉了声网
     * 3、申请开播接口成功返回了，token，渠道名，liveId, 声网的初始化。
     * 4、声网初始化完成及加入频道成功后，RtcEventHandler的onJoinChannelSuccess将收到回调
     * 5、在回调中执行，推流操作，请求我们的服务端推流接口。
     */

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        XXPermissions.with(this).permission(Permission.RECORD_AUDIO, Permission.CAMERA)
            .request { permissions, all ->

                if (!all) {
                    longToast("获取部分权限成功，但部分权限未正常授予")
                    return@request
                }
                intent.getParcelableExtra<LocalData.LiveMessage>("live_message")?.apply {
                    val file = File(liveBg)
                    longToast(liveBg)
                    val requestBody: RequestBody =
                        RequestBody.create("multipart/form-data".toMediaTypeOrNull(), file)
                    liveCoverImage =
                        MultipartBody.Part.createFormData("liveCoverImage", file.name, requestBody)

                    //申请开播
                    viewModel.openLive(liveType, liveName, liveCoverImage, lat, lng)
                }

            }


        bind.closeLive.setOnClickListener {
            //关闭直播
            viewModel.closeLive()
            finish()
        }

        viewModel.liveData.observe(this) {
            try {
                if (it.liveId != null) {
                    liveId = it.liveId
                }
                if (it.channelName != null && it.liveId != null && it.agoraToken != null) {
                    initializeAndJoinChannel(it.channelName, it.agoraToken)
                }
                it.compositeWsUrl?.let { it1 -> connectSocket(it1) }
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }

        //消息列表初始化
        bind.massageList.apply {
            mAdapter = MyAdapter(ArrayList<String>())
            adapter = mAdapter
            layoutManager = LinearLayoutManager(baseContext)

        }
        //连麦请求列表，获取到，通过统一某一个用户，都是在调用我们都服务器接口
        //当我们当服务器返回同意连麦成功
    }


    private fun initializeAndJoinChannel(channelName: String, agoraToken: String) {

        try {
            val config = RtcEngineConfig()
            config.mContext = baseContext
            config.mAppId = appId
            //事件处理，mEventHandler
            config.mEventHandler = mRtcEventHandler
            mRtcEngine = RtcEngine.create(config)?.apply {
                // 视频默认禁用，你需要调用 enableVideo 启用视频流。
                enableVideo()
                // 开启本地视频预览。
                startPreview()
                val container = bind.localVideoViewContainer
                // 创建一个 SurfaceView 对象，并将其作为 FrameLayout 的子对象。
                val surfaceView = SurfaceView(baseContext)
                container.addView(surfaceView)
                // 将 SurfaceView 对象传入声网，以渲染本地视频。
                //userId,我们自己的。
                setupLocalVideo(
                    VideoCanvas(
                        surfaceView,
                        VideoCanvas.RENDER_MODE_FIT,
                        getUserId() ?: 0
                    )
                )
                val options = ChannelMediaOptions()
                // 根据场景将用户角色设置为 BROADCASTER 或 AUDIENCE。
                options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER
                // 直播场景下，设置频道场景为 BROADCASTING。
                options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING
                // 使用临时 Token 加入频道。
                // 你需要自行指定用户 ID，并确保其在频道内的唯一性。
                joinChannel(agoraToken, channelName, getUserId() ?: 0, options)
            }
        } catch (e: Exception) {
            throw RuntimeException("Check the error.")
        }
    }

    private fun connectSocket(compositeWsUrl: String) {
        val webSocketUtils: WebSocketUtils = WebSocketUtils().startConnect(compositeWsUrl, this)
        webSocketUtils.setOnMessageListener(object : WebSocketUtils.OnMessageListener {
            override fun message(msg: String?) {
                Toast.makeText(this@OpenLiveActivity,msg.toString(), Toast.LENGTH_LONG).show();
                Log.d("connectSocket msg", msg.toString())
                mAdapter.data.add(msg.toString())
                mAdapter.notifyDataSetChanged()
                bind.massageZone.visibility = View.VISIBLE
                val socketBean = Gson().fromJson(msg, LocalData.WebSocketInfo::class.java)
                when (socketBean.msgType) {
                    101 -> {

                    }
                    102 -> {
                        val numInfo = Gson().fromJson(msg, LocalData.LiveNumber::class.java)
                        longToast(numInfo.num.toString())
                    }
                    103 -> {
                        val bridge = Gson().fromJson(msg, LocalData.Bridge::class.java)
                        when (bridge.status) {
                            101 -> {}
                            102 -> {}
                            103 -> {}
                        }
                    }
                    104 -> {
                        val link = Gson().fromJson(msg, LocalData.Link::class.java)
                        longToast(link.toString())
                    }
                }
            }
        })
    }
    /**
     * 这是远端数据
     */
    private fun setupRemoteVideo(uid: Int) {
        val container = bind.remoteVideoViewContainer
        bind.remoteVideoViewContainer.visibility = View.VISIBLE
        val surfaceView = SurfaceView(baseContext)
        surfaceView.setZOrderMediaOverlay(true)
        container.removeAllViews()
        container.addView(surfaceView)
        mRtcEngine?.setupRemoteVideo(VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid))
    }

    override fun onDestroy() {
        super.onDestroy()
        mRtcEngine?.stopPreview()
        mRtcEngine?.leaveChannel()
    }

    class MyAdapter(val data: ArrayList<String>) : Adapter<BindingViewHolder<ItemLiveMessageZoneBinding>>() {
        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): BindingViewHolder<ItemLiveMessageZoneBinding> {
            return newBindingViewHolder(parent)
        }

        override fun getItemCount(): Int  = data.size

        override fun onBindViewHolder(
            holder: BindingViewHolder<ItemLiveMessageZoneBinding>,
            position: Int
        ) {
            holder.binding.itemMassageText.text = data[position]
        }

    }
}